 <template>
    <el-tooltip effect="dark" :content="value" :disabled="!isTip" ref="tip">
      <!-- v-bind="$attrs" v-on="$listeners"这样写只要组件没有拦截配置和事件，父组件中可以直接配置el-input -->
      <el-input
        ref="input"
        v-model="inputValue"
        v-bind="$attrs"
        v-on="$listeners"
        @input="onInput"
        ></el-input>
  </el-tooltip>
</template>
<script lang="ts">
import { Component, Vue, Model, Emit, Watch } from 'vue-property-decorator';
// el-input组件增强，当文字内容过长超过输入框宽度时，移动上去会浮动显示输入内容, 用法和el-input一样
@Component({
  name: 'zbTipInput'
})
export default class ZbTipInput extends Vue {
  private inputValue: string = '' // 输入框值

  private isTip: boolean = false // 是否显示tip

  private isInit: boolean = true // 是否初始化
  // v-model绑定值
  @Model('change', { type: String }) private value!: string
  @Emit('change') private setValue () { console.log() }
  // 抛出input事件
  @Emit('input') private input () { console.log() }
  // 监听v-model绑定值
  @Watch('value')
  private updateValue (v: string) {
    const me = this as any
    // 设值输入框的值
    me.inputValue = v
    // 视图绘制完处理逻辑
    me.$nextTick(() => {
      const input = me.$refs.input.getInput()
      // 判断输入框文字内容是否超过输入框宽度
      const isTip = input.offsetWidth < input.scrollWidth
      // 标识是否显示tip
      me.isTip = isTip
      if (isTip) {
        if (!me.isInit) {
        // 如果文字内容超长，并且不是初始化状态
          // 显示tip提示
          const tip = me.$refs.tip
          // 执行这个方法后tip提示才能实时显示
          tip.updatePopper()
          // 显示tip
          tip.show()
        } else {
          // 标识初始化完毕
          me.isInit = false
        }
      }
    })
  }

  // 输入内容改变时
  private onInput (v: string) {
    const me = this as any
    // 更新v-model绑定值
    me.setValue(v)
    // 组件拦截了el-input的input事件，这里手动抛出同样的事件
    me.input(v)
  }

  private mounted () {
    if (this.value) {
      this.inputValue = this.value
    }
  }
}
</script>
